﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DogJson
{

    [Collection(typeof(DictionaryKV<,>))]
    public unsafe class CollectionArrayDictionaryKV<K, V> : CollectionArrayBase
    {
        TypeCode typeCodeK;
        TypeCode typeCodeV;
        public CollectionArrayDictionaryKV()
        {
            typeCodeK = Type.GetTypeCode(typeof(K));
            typeCodeV = Type.GetTypeCode(typeof(V));
        }
        public override void Add(object obj, int index, object value)
        {
            DictionaryKV<K, V> kv = (DictionaryKV<K, V>)obj;
            if (index == 0)
            {
                kv.k = (K)value;
            }
            else
            {
                kv.v = (V)value;
            }
        }

        public override void AddValue(object obj, int index, char* str, JsonValue value)
        {
            DictionaryKV<K, V> kv = (DictionaryKV<K, V>)obj;
            TypeCode typeCode;
            object set_value;
            if (index == 0)
            {
                set_value = default(K);
                typeCode = typeCodeK;
            }
            else
            {
                set_value = default(V);
                typeCode = typeCodeV;
            }
            switch (value.type)
            {
                case JsonValueType.String:
                    switch (typeCode)
                    {
                        case TypeCode.Char:
                            set_value = str[value.vStringStart];
                            break;
                        case TypeCode.String:
                            set_value = new string(str, value.vStringStart, value.vStringLength);
                            break;
                    }
                    break;
                case JsonValueType.Long:
                    switch (typeCode)
                    {
                        case TypeCode.SByte:
                            set_value = (SByte)value.valueLong;
                            break;
                        case TypeCode.Byte:
                            set_value = (Byte)value.valueLong;
                            break;
                        case TypeCode.Int16:
                            set_value = (Int16)value.valueLong;
                            break;
                        case TypeCode.UInt16:
                            set_value = (UInt16)value.valueLong;
                            break;
                        case TypeCode.Int32:
                            set_value = (Int32)value.valueLong;
                            break;
                        case TypeCode.UInt32:
                            set_value = (UInt32)value.valueLong;
                            break;
                        case TypeCode.Int64:
                            set_value = value.valueLong;
                            break;
                        case TypeCode.UInt64:
                            set_value = (UInt64)value.valueLong;
                            break;
                        case TypeCode.Single:
                            set_value = (Single)value.valueLong;
                            break;
                        case TypeCode.Double:
                            set_value = (Double)value.valueLong;
                            break;
                        case TypeCode.Decimal:
                            set_value = (Decimal)value.valueLong;
                            break;
                    }
                    break;
                case JsonValueType.Double:
                    switch (typeCode)
                    {
                        case TypeCode.Single:
                            set_value = (Single)value.valueDouble;
                            break;
                        case TypeCode.Double:
                            set_value = (Double)value.valueDouble;
                            break;
                        case TypeCode.Decimal:
                            set_value = (Decimal)value.valueDouble;
                            break;
                    }
                    break;
                case JsonValueType.Boolean:
                    set_value = value.valueBool;
                    break;
            }

            if (index == 0)
            {
                kv.k = (K)set_value;
            }
            else
            {
                kv.v = (V)set_value;
            }

        }


        public override object CreateArray(int arrayCount, Type arrayType, Type parentType)
        {
            return new DictionaryKV<K, V>();
        }
        public override Type ItemType(int index)
        {
            if (index == 0)
            {
                return typeof(K);
            }
            return typeof(V);
        }
    }

    public class DictionaryKV<K, V>
    {
        public K k;
        public V v;
    }

    [Collection(typeof(Dictionary<,>))]
    public class CollectionArrayDictionary<K, V> : CollectionArrayBase
    {
        public override void Add(object obj, int index, object value)
        {
            var dict = (Dictionary<K, V>)obj;
            var kv = (DictionaryKV<K, V>)value;
            dict[kv.k] = kv.v;
        }

        public override object CreateArray(int arrayCount, Type arrayType, Type parentType)
        {
            return new Dictionary<K, V>(arrayCount);
        }
        public override object End(object obj)
        {
            return obj;
        }
        public override Type ItemType(int index)
        {
            return typeof(DictionaryKV<K, V>);
        }
    }


}
